<template>
  <Header/>
  <div class="main-container">
    <el-card class="personal-page">
      <el-page-header @back="goBack" content="个人中心"/>

      <el-divider/>

      <el-row :gutter="20">
        <el-col :span="8">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>个人信息</span>
                <el-button type="text" @click="showPasswordDialog">修改密码</el-button>
              </div>
            </template>
            <el-descriptions :column="1" border>
              <el-descriptions-item label="头像">
                <el-upload
                    ref="avatarUploadRef"
                    class="avatar-uploader"
                    action="#"
                    :show-file-list="false"
                    :before-upload="beforeAvatarUpload"
                    :http-request="updateAvatar"
                    :auto-upload="true"
                >
                  <div class="avatar-wrapper">
                    <el-image
                        :src="userPic"
                        style="width: 60px; height: 60px; border-radius: 50%;"
                        fit="cover"
                    />
                  </div>
                  <template #tip>
                    <div class="el-upload__tip">点击头像可上传新头像</div>
                  </template>
                </el-upload>

              </el-descriptions-item>

              <el-descriptions-item label="用户名">
                <el-tag type="info">{{ username }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="邮箱">
                <el-tag type="info">{{ email }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="电话">
                <el-tag type="info">{{ phone }}</el-tag>
              </el-descriptions-item>
            </el-descriptions>
          </el-card>
        </el-col>

        <el-col :span="16">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>已发布文章</span>
                <el-button type="primary" size="small" @click="showPublishDialog">发布新文章</el-button>
              </div>
            </template>

            <el-empty v-if="blogs.length === 0" description="暂无文章，点击发布新文章吧"/>

            <div v-else class="blog-cards">
              <div v-for="(blog, index) in blogs" :key="index" class="blog-card" @click="navigateToArticle(blog.id)">
                <h3>{{ blog.title }}</h3>
                <p>
                  <!--                <v-md-preview-html :html="html[index]" preview-class="vuepress-markdown-body"/>-->
                  <MdPreview :html="html[index]"/>
                </p>
                <div class="meta-info">
                  <el-tag type="success">原创</el-tag>
                  <span>发布博客 {{ blog.time | relativeTime }}前</span>
                  <span>·</span>
                  <span>{{ blog.readCount }}阅读</span>
                  <span>·</span>
                  <span>{{ blog.likeCount }}点赞</span>
                  <span>·</span>
                  <span>{{ blog.commentCount }}评论</span>
                  <span>·</span>
                  <span>{{ blog.favoriteCount }}收藏</span>
                  <el-button type="text" @click.stop="editBlog(index)" style="float: right;">编辑</el-button>
                  <el-button type="text" @click.stop="deleteBlog(blog.id)"
                             style="float: right; margin-right: 10px; color: #f56c6c;">删除
                  </el-button>
                </div>

              </div>
            </div>
          </el-card>
          <el-pagination
              v-if="blogs.length > 0"
              v-model:current-page="pagination.currentPage"
              v-model:page-size="pagination.pageSize"
              :total="pagination.total"
              :page-sizes="[5, 10, 20, 30]"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
          />

        </el-col>
      </el-row>

      <!-- 发布文章对话框 -->
      <el-dialog v-model="dialogVisible" title="发布新文章" width="50%">
        <el-form :model="newBlog" label-width="80px">
          <el-form-item label="文章标题" prop="title">
            <el-input v-model="newBlog.title" placeholder="请输入标题"/>
          </el-form-item>
          <el-form-item label="文章内容" prop="content">
            <el-input
                v-model="newBlog.content"
                type="textarea"
                :rows="5"
                placeholder="请输入内容"
            />
          </el-form-item>
        </el-form>
        <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="publishBlog">发布</el-button>
        </span>
        </template>
      </el-dialog>

      <!-- 修改密码对话框 -->
      <el-dialog v-model="passwordDialogVisible" title="修改密码" width="50%">
        <el-form :model="passwordForm" :rules="passwordRules" ref="passwordFormRef" label-width="100px">
          <el-form-item label="原密码" prop="password">
            <el-input v-model="passwordForm.password" type="password" show-password></el-input>
          </el-form-item>
          <el-form-item label="新密码" prop="newPwd">
            <el-input v-model="passwordForm.newPwd" type="password" show-password></el-input>
          </el-form-item>
          <el-form-item label="确认密码" prop="confirmPwd">
            <el-input v-model="passwordForm.confirmPwd" type="password" show-password></el-input>
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button @click="passwordDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitPasswordChange">确认修改</el-button>
        </template>
      </el-dialog>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import {onMounted, ref, reactive} from 'vue';
import Header from '@/components/Header.vue';
import router from '@/router';
import request from '@/api/request';
import VueMarkdownEditor, {xss} from "@kangc/v-md-editor";
import createLineNumbertPlugin from '@kangc/v-md-editor/lib/plugins/line-number/index';
import '@kangc/v-md-editor/lib/plugins/copy-code/copy-code.css';
import createCopyCodePlugin from '@kangc/v-md-editor/lib/plugins/copy-code/index';
import {ElMessage, ElMessageBox} from "element-plus";
import MdPreview from "./md-prvive.vue";

VueMarkdownEditor.use(createLineNumbertPlugin());
VueMarkdownEditor.use(createCopyCodePlugin());

// 用户信息
const username = ref('');
const email = ref('');
const phone = ref('');
const userPic = ref('');
const html = ref<string[]>([]);

// 文章数据
const blogs = ref<{
  id: number;
  title: string;
  content: string;
  time: string;
  readCount: number;
  likeCount: number;
  commentCount: number;
  favoriteCount: number;
}[]>([]);

// 新文章数据
const newBlog = ref({
  title: '',
  content: '',
});

// 对话框控制
const dialogVisible = ref(false);

// 密码修改相关
const passwordDialogVisible = ref(false);
const passwordFormRef = ref();
const passwordForm = reactive({
  password: '',
  newPwd: '',
  confirmPwd: ''
});

const passwordRules = {
  password: [{required: true, message: '请输入原密码', trigger: 'blur'}],
  newPwd: [
    {required: true, message: '请输入新密码', trigger: 'blur'},
    {min: 6, max: 20, message: '密码长度在6到20个字符', trigger: 'blur'}
  ],
  confirmPwd: [
    {required: true, message: '请再次输入新密码', trigger: 'blur'},
    {
      validator: (rule: any, value: string, callback: any) => {
        if (value !== passwordForm.newPwd) {
          callback(new Error('两次输入密码不一致'));
        } else {
          callback();
        }
      }, trigger: 'blur'
    }
  ]
};

const showPublishDialog = () => {
  router.push('/AddArticle');
};
// 在用户信息部分添加头像上传相关代码
const avatarUploadRef = ref();
const avatarUploading = ref(false);

const updateAvatar = (file: File) => {
  console.log('updateAvatar', file)
  avatarUploading.value = true;
  const formData = new FormData();
  formData.append('avatar', file);

  request.patch('/user/updateAvatar', formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  }).then((res: any) => {
    userPic.value = res.data.avatarUrl;
    ElMessage.success('头像更新成功');
  }).catch((error: any) => {
    ElMessage.error(error.message || '头像更新失败');
  }).finally(() => {
    avatarUploading.value = false;
  });
};

const beforeAvatarUpload = (file: File) => {
  const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
  const isLt2M = file.size / 1024 / 1024 < 2;

  if (!isJPG) {
    ElMessage.error('头像图片只能是 JPG/PNG 格式!');
    return false;
  }
  if (!isLt2M) {
    ElMessage.error('头像图片大小不能超过 2MB!');
    return false;
  }
  return true;
};


// 头像上传成功处理
const handleAvatarSuccess = (response: any, file: File) => {
  updateAvatar(file);
};

const publishBlog = () => {
  if (newBlog.value.title && newBlog.value.content) {
    const currentTime = new Date().toLocaleString();
    blogs.value.push({
      id: blogs.value.length + 1,
      ...newBlog.value,
      time: currentTime,
      readCount: 0,
      likeCount: 0,
      commentCount: 0,
      favoriteCount: 0,
    });
    newBlog.value.title = '';
    newBlog.value.content = '';
    dialogVisible.value = false;
  }
};

const editBlog = (index: number) => {
  const blogId = blogs.value[index].id;
  router.push({
    path: '/AddArticle',
    query: {
      id: blogId,
      title: blogs.value[index].title,
      content: blogs.value[index].content,
      // 其他需要传递的文章信息
    }
  });
};
const deleteBlog = async (articleId: number) => {
  try {
    // 先弹出确认对话框
    await ElMessageBox.confirm('确定要删除这篇文章吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });

    // 调用删除接口
    await request.delete('/article/delArticle', {
      params: { articleId }
    });

    ElMessage.success('删除成功');

    // 重新获取文章列表
    fetchBlogs();

  } catch (error: any) {
    // 用户点击了取消
    if (error === 'cancel') {
      return;
    }
    ElMessage.error(error.message || '删除失败');
  }
};

const goBack = () => {
  router.back();
};

const navigateToArticle = (id: number) => {
  router.push(`/articleDetail/${id}`);
};

const showPasswordDialog = () => {
  passwordForm.password = '';
  passwordForm.newPwd = '';
  passwordForm.confirmPwd = '';
  passwordDialogVisible.value = true;
};

const submitPasswordChange = () => {
  passwordFormRef.value.validate((valid: boolean) => {
    if (valid) {
      request.patch('/user/updatePwd', {
        password: passwordForm.password,
        newPwd: passwordForm.newPwd
      }).then(() => {
        ElMessage.success('密码修改成功');
        passwordDialogVisible.value = false;
      }).catch((error: any) => {
        ElMessage.error(error.message || '密码修改失败');
      });
    }
  });
};
// 分页数据
const pagination = reactive({
  currentPage: 1,
  pageSize: 5,
  total: 0
});

// 分页大小改变
const handleSizeChange = (val: number) => {
  pagination.pageSize = val;
  fetchBlogs();
};

// 当前页改变
const handleCurrentChange = (val: number) => {
  pagination.currentPage = val;
  fetchBlogs();
};
const fetchBlogs = async () => {
  try {
    const res = await request.get('/user/getArticle', {
      params: {
        pageNum: pagination.currentPage,
        pageSize: pagination.pageSize
      }
    });

    blogs.value = res.data.items;
    pagination.total = res.data.total;

    const renderedContents = res.data.items.map((item: any) => {
      const markdownContent = item.content;
      const renderedHtml = VueMarkdownEditor.vMdParser.themeConfig.markdownParser.render(markdownContent);
      return xss.process(renderedHtml);
    });

    html.value = renderedContents;

    // 如果当前页没有数据且不是第一页，则自动跳转到上一页
    if (blogs.value.length === 0 && pagination.currentPage > 1) {
      pagination.currentPage--;
      fetchBlogs();
    }
  } catch (error) {
    ElMessage.error('获取文章列表失败');
  }
};

onMounted(() => {
  // 获取个人信息
  request.get('/user/userInfo').then((res: any) => {
    username.value = res.data.username;
    email.value = res.data.email;
    phone.value = res.data.phone;
    userPic.value = res.data.userPic;
  });
// 获取文章数据
  fetchBlogs();

});

// 时间相对化过滤器
const relativeTime = (time: string): string => {
  const now = new Date();
  const postTime = new Date(time);
  const diff = now.getTime() - postTime.getTime();
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(diff / (1000 * 60));
  const hours = Math.floor(diff / (1000 * 60 * 60));
  const days = Math.floor(diff / (1000 * 60 * 60 * 24));

  if (seconds < 60) {
    return `${seconds}秒`;
  } else if (minutes < 60) {
    return `${minutes}分钟`;
  } else if (hours < 24) {
    return `${hours}小时`;
  } else {
    return `${days}天`;
  }
};
</script>

<style>
.main-container .personal-page {
  transform: translateY(80px);
  width: 90%;
  height: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.main-container .card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.main-container .card-header .el-button {
  padding: 0;
  margin-left: 10px;
}

.main-container .blog-desc,
.main-container .blog-desc * h2 {
  /*font-family: "楷体", KaiTi, "STKaiti", serif !important;*/
  font-size: 14px !important;
}

.main-container .blog-cards {
  margin-top: 20px;
}

.main-container .blog-card {
  border: 1px solid #eee;
  border-radius: 8px;
  padding: 15px;
  height: 180px;
  display: flex;
  flex-direction: column;
  margin-bottom: 20px;
}

.main-container .blog-card p {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  margin-bottom: 8px;
}

.main-container .blog-card h3 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 8px;
}

.main-container .meta-info {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #999;
  margin-top: auto;
  padding-top: 8px;
}

.main-container .meta-info .el-tag + span {
  margin-left: 10px;
}

.main-container .avatar-uploader {
  display: inline-block;
  position: relative;
  cursor: pointer;
}

.main-container .avatar-uploader:hover .el-image::after {
  content: '更换头像';
  position: absolute;
  top: 0;
  left: 0;
  width: 60px;
  height: 60px;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  cursor: pointer;
}


.main-container .el-upload__tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

</style>
